/**
 * @file system_utils.h
 * @brief 系统初始化和工具函数
 * @version 2.0
 * @date 2023-05-20
 */

#ifndef SYSTEM_UTILS_H
#define SYSTEM_UTILS_H

#include <stdbool.h>
#include <signal.h>
#include <stdint.h>
#include "common_defs.h" // 包含通用定义，确保使用统一的类型和常量

// 标记未使用的变量或函数，避免编译警告
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif

#ifdef __cplusplus
extern "C" {
#endif

// 系统配置结构体
typedef struct {
    // 日志配置
    LogLevel log_level;
    char log_file[MAX_PATH_LENGTH];
    bool console_log;
    
    // 运行模式
    bool simulation_mode;
    
    // 采样间隔（毫秒）
    int sampling_interval_ms;
    
    // 工作目录
    char work_dir[MAX_PATH_LENGTH];
    
    // 配置文件路径
    char config_file[MAX_PATH_LENGTH];
} SystemConfig;

// 全局系统配置
extern SystemConfig g_system_config;

// 运行控制标志
extern volatile bool g_running;

/**
 * @brief 设置日志级别
 * 
 * @param level 日志级别
 */
void set_log_level(LogLevel level);

/**
 * @brief 输出日志信息
 * 
 * @param level 日志级别
 * @param format 格式化字符串
 * @param ... 变参列表
 */
void log_message(LogLevel level, const char *format, ...);

/**
 * @brief 初始化日志系统（从logger.h合并）
 * 
 * @param log_file 日志文件路径，NULL表示仅输出到控制台
 * @param console_output 是否同时输出到控制台
 * @param min_level 最低记录的日志级别
 * @return int 成功返回0，失败返回非0值
 */
int init_logger(const char* log_file, bool console_output, LogLevel min_level);

/**
 * @brief 关闭日志系统（从logger.h合并）
 */
void cleanup_logger(void);

/**
 * @brief 初始化系统
 * 
 * @param argc 命令行参数数量
 * @param argv 命令行参数数组
 * @return int 成功返回0，失败返回非0
 */
int init_system(int argc, char **argv);

/**
 * @brief 初始化系统工具（日志等）
 * 
 * @param log_file 日志文件路径
 * @param log_level 日志级别
 * @return int 成功返回0，失败返回非0
 */
int init_system_utils(const char *log_file, LogLevel log_level);

/**
 * @brief 清理系统资源
 */
void cleanup_system_utils(void);

/**
 * @brief 打印系统信息
 */
void print_system_info(void);

/**
 * @brief 获取当前时间戳（毫秒）
 * 
 * @return uint64_t 时间戳
 */
uint64_t get_timestamp_ms(void);

/**
 * @brief 获取当前工作目录
 * 
 * @param buffer 输出缓冲区 
 * @param size 缓冲区大小
 * @return int 成功返回0，失败返回非0
 */
int get_current_dir(char *buffer, size_t size);

/**
 * @brief 创建目录（如果不存在）
 * 
 * @param path 目录路径
 * @return int 成功返回0，失败返回非0
 */
int create_directory(const char *path);

/**
 * @brief 检查文件是否存在
 * 
 * @param filename 文件名
 * @return true 存在
 * @return false 不存在
 */
bool file_exists(const char *filename);

/**
 * @brief 获取格式化的当前时间字符串
 * 
 * @param buffer 输出缓冲区
 * @param size 缓冲区大小
 * @param format 时间格式（如 "%Y-%m-%d %H:%M:%S"）
 */
void get_formatted_time(char *buffer, size_t size, const char *format);

// ============================= 以下是系统诊断功能 =============================

// 系统组件枚举
typedef enum {
    COMPONENT_SYSTEM = 0,     // 整体系统
    COMPONENT_SENSOR,         // 传感器子系统
    COMPONENT_VISUAL,         // 视觉子系统
    COMPONENT_STEREO,         // 立体视觉子系统
    COMPONENT_STORAGE,        // 存储子系统
    COMPONENT_NETWORK,        // 网络子系统
    COMPONENT_COUNT           // 组件总数
} SystemComponent;

// 健康状态枚举
typedef enum {
    HEALTH_UNKNOWN = 0,       // 未知状态
    HEALTH_NORMAL,            // 正常
    HEALTH_WARNING,           // 警告
    HEALTH_ERROR,             // 错误
    HEALTH_CRITICAL           // 严重错误
} HealthStatus;

// 系统资源使用情况
typedef struct {
    float cpu_usage;           // CPU使用率(%)
    float memory_usage;        // 内存使用率(%)
    float disk_usage;          // 磁盘使用率(%)
    uint64_t free_disk_space;  // 剩余磁盘空间(字节)
    float temperature;         // 系统温度(°C)，如果可用
    float battery_level;       // 电池电量(%)，如果可用
} SystemResources;

// 组件状态结构体
typedef struct {
    HealthStatus health;           // 健康状态
    uint8_t health_score;          // 健康分数(0-100)
    char status_message[256];      // 状态消息
    uint64_t last_check_time;      // 上次检查时间
    uint32_t error_count;          // 错误计数
    uint32_t warning_count;        // 警告计数
    bool recovery_needed;          // 是否需要恢复
    bool recovery_in_progress;     // 恢复是否进行中
} ComponentStatus;

// 系统诊断状态
typedef struct {
    ComponentStatus components[COMPONENT_COUNT]; // 各组件状态
    SystemResources resources;                   // 系统资源
    uint64_t uptime_ms;                         // 系统运行时间(毫秒)
    uint64_t last_diagnostics_time;             // 上次诊断时间
    bool watchdog_enabled;                       // 看门狗是否启用
    uint32_t watchdog_reset_count;               // 看门狗重置计数
} DiagnosticsState;

/**
 * @brief 初始化系统诊断模块
 * 
 * @param enable_watchdog 是否启用看门狗
 * @return int 成功返回0，失败返回非0
 */
int init_diagnostics(bool enable_watchdog);

/**
 * @brief 清理系统诊断模块
 */
void cleanup_diagnostics(void);

/**
 * @brief 启动诊断线程
 * 
 * @return int 成功返回0，失败返回非0
 */
int start_diagnostics_thread(void);

/**
 * @brief 停止诊断线程
 * 
 * @return int 成功返回0，失败返回非0
 */
int stop_diagnostics_thread(void);

/**
 * @brief 执行系统诊断
 * 
 * @param full_diagnostics 是否执行完整诊断
 * @return int 成功返回0，失败返回非0
 */
int perform_diagnostics(bool full_diagnostics);

/**
 * @brief 获取系统诊断状态
 * 
 * @param state 输出状态结构体指针
 * @return int 成功返回0，失败返回非0
 */
int get_diagnostics_state(DiagnosticsState *state);

/**
 * @brief 获取组件健康状态
 * 
 * @param component 组件枚举值
 * @return HealthStatus 健康状态
 */
HealthStatus get_component_health(SystemComponent component);

/**
 * @brief 获取组件健康分数(0-100)
 * 
 * @param component 组件枚举值
 * @return uint8_t 健康分数
 */
uint8_t get_component_health_score(SystemComponent component);

/**
 * @brief 获取系统整体健康状态
 * 
 * @return HealthStatus 健康状态
 */
HealthStatus get_system_health(void);

/**
 * @brief 获取系统整体健康分数(0-100)
 * 
 * @return uint8_t 健康分数
 */
uint8_t get_system_health_score(void);

/**
 * @brief 重置看门狗计时器
 * 必须定期调用此函数，否则系统会自动重启
 */
void reset_watchdog(void);

/**
 * @brief 尝试自动恢复组件
 * 
 * @param component 组件枚举值
 * @return bool 成功返回true，失败返回false
 */
bool try_recover_component(SystemComponent component);

/**
 * @brief 获取系统资源使用情况
 * 
 * @param resources 输出资源结构体指针
 * @return int 成功返回0，失败返回非0
 */
int get_system_resources(SystemResources *resources);

/**
 * @brief 记录诊断事件
 * 
 * @param component 组件枚举值
 * @param status 健康状态
 * @param format 消息格式
 * @param ... 可变参数
 */
void log_diagnostic_event(SystemComponent component, HealthStatus status, const char *format, ...);

/**
 * @brief 获取组件名称
 * 
 * @param component 组件枚举值
 * @return const char* 组件名称字符串
 */
const char* get_component_name(SystemComponent component);

/**
 * @brief 获取健康状态名称
 * 
 * @param status 健康状态枚举值
 * @return const char* 健康状态名称字符串
 */
const char* get_health_status_name(HealthStatus status);

#ifdef __cplusplus
}
#endif

#endif /* SYSTEM_UTILS_H */ 